package com.wyg.blog.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wyg.blog.utils.ApiLimit;
import com.wyg.blog.utils.RedisUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:    拦截器,控制后端接口访问次数,预防攻击.    配置拦截规则,暂时弃用,后期如果有必要则开启使用
 * @author: WYG
 * @time: 2021/2/4 21:10
 */
@Component
public class LimitInterceptor extends HandlerInterceptorAdapter {
    // 引入redis工具类
    @Resource
    RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //判断方法中是否有注解
            ApiLimit apiLimit = handlerMethod.getMethodAnnotation(ApiLimit.class);
            if (apiLimit == null) {
                return true;
            }
            int seconds = apiLimit.seconds();
            int maxCount = apiLimit.maxCount();
            // 根据名称获取get请求对应的请求参数
            String key = request.getParameter("ipAddress");
            boolean has = redisUtil.hasKey(key);
            if (has) {
                Integer counts = (Integer) redisUtil.get(key);
                // 如果大于规定时间的访问次数就拦截该请求
                if (counts > maxCount) {
                    return false;
                }
                redisUtil.incr(key, 1);
            } else {
                redisUtil.set(key, 1, seconds);
            }
        }
        return true;
    }

    public void render(HttpServletResponse response) throws IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Method", "POST,GET");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        Map resultMap = new HashMap();
        resultMap.put("code", "200");
        resultMap.put("msg", "接口访问次数超限!");
        resultMap.put("data", "请注意访问次数");
        out.write(new ObjectMapper().writeValueAsString(resultMap));
        out.flush();
        out.close();
    }
}
